﻿import flash.display.BitmapData;
class Math2 {


	//-------------------- 求两直线交点函数 p-参数：[x0,y0,x1,y1,x2,y2,x3,y3][,fun1,fun2][,k1,b1,k2,b2] 三种方式x、y为已知两点,fun为已知两直线方程，k、b为已知两方程的k、b参数返回point类型(.x .y)交点
	public static function Xpoint(p:Object):Object {
		var lx:Number = -1;
		if (p.x0 != undefined) {
			if (p.y0 == undefined || p.x1 == undefined || p.y1 == undefined || p.y2 == undefined || p.x2 == undefined || p.y3 == undefined || p.x3 == undefined) {
				trace("交点方程:两点数据不正确");
				return null;
			}
			lx = 0;
		}
		if (p.fun1 != undefined || p.fun2 != undefined) {
			lx = 1;
		}
		if (p.fun1 != undefined && p.fun2 != undefined) {
			if (lx == 1) {
				lx = 1;
			} else {
				lx = 2;
				//有一个函数没有。
				trace("交点方程:两直线方程少一个");
				return null;
			}
		}
		if (lx<=0) {
			if (p.k1 != undefined && p.k2 != undefined && p.b1 != undefined && p.b2 != undefined) {
				lx = 3;
			} else {
				if (lx == -1) {
					trace("交点方程:两方程参数k或b值不正确");
					return null;
				}
			}
		}
		var k1:Number = 0;
		var k2:Number = 0;
		var b1:Number = 0;
		var b2:Number = 0;
		//trace("交点计算类型："+lx);
		switch (lx) {
		case 0 :
			var f1 = Math2.lineEquation({x0:p.x0, y0:p.y0, x1:p.x1, y1:p.y1});
			var f2 = Math2.lineEquation({x0:p.x2, y0:p.y2, x1:p.x3, y1:p.y3});
			k1 = f1("k");
			k2 = f2("k");
			b1 = f1("b");
			b2 = f2("b");
			break;
		case 1 :
			k1 = p.fun1("k");
			k2 = p.fun2("k");
			b1 = p.fun1("b");
			b2 = p.fun2("b");
			break;
		case 2 :
			break;
		case 3 :
			k1 = p.k1;
			k2 = p.k2;
			b1 = p.b1;
			b2 = p.b2;
			break;
		}
		var ro:Object = new Object();
		if (k2 == k1) {
			trace("交点方程:无交点（平行）");
			return null;
		} else {
			
			ro.x = (b1-b2)/(k2-k1);
			ro.y = k1*ro.x+b1;
			//trace("Nan:"+b1+" "+b2+" "+k2+" "+k1);
			return ro;
		}
	}
	//------------- 建立直线方程 p-参数包含：x0,y0,x1,y1[,k,x2,y2] f-是否构建与之垂直的方程函数
	public static function lineEquation(p:Object, f:Boolean):Function {
		//Debug.traceAllObj(p);
		var lx:Number = 0;
		if (p.k != undefined) {
			lx = 1;
		} else {
			lx = 0;
		}
		if (lx == 0) {
			if (p.x0 != undefined && p.y0 != undefined) {
				if (p.x1 == undefined) {
					p.x1 = 0;
				}
				if (p.y1 == undefined) {
					p.y1 = 0;
				}
				if (f == undefined) {
					f = false;
				} else if (f == true) {
					if (p.x2 == undefined) {
						p.x2 = 0;
					}
					if (p.y2 == undefined) {
						p.y2 = 0;
					}
				}
			} else {
				trace("Math2:第一个点参数不能为空");
				return null;
			}
		}
		if (lx == 1) {
			if (p.k == undefined || Number(p.k) == "NaN") {
				trace("Math2:K常数不正确");
				return null;
			}
			if (p.x0 == undefined) {
				p.x0 = 0;
			}
			if (p.y0 == undefined) {
				p.y = 0;
			}
			if (f == undefined) {
				f = false;
			} else if (f == true) {
				if (p.x2 == undefined) {
					p.x2 = 0;
				}
				if (p.y2 == undefined) {
					p.y2 = 0;
				}
			}
		}
		var k:Number = 0;
		var b:Number = 0;
		if (!f) {
			switch (lx) {
			case 0 :
				var xl:Number = p.x1-p.x0;
				var yl:Number = p.y1-p.y0;
				k = yl/xl;
				if(p.x1==0){
					//trace("??"+xl+"|"+yl)
					b = p.y1;
				}else{
					if(k==Infinity){
						//trace("??");
						b=-Infinity;
					}
					else if(k==-Infinity){
						b=Infinity
					}else{
						//trace("???")
						b = p.y1-k*p.x1;
					}
				}
				//trace(b+"|"+k);
				
				
				break;
			case 1 :
				k = p.k;
				if(k==Infinity || k==-Infinity){
					b = p.y2;
				}else{
					b = p.y2-k*p.x2;
				}
				break;
			}
		} else {
			switch (lx) {
			case 0 :
				var xl:Number = p.x1-p.x0;
				var yl:Number = p.y1-p.y0;
				k = xl/yl;
				if(k==Infinity || k==-Infinity){
					b = p.y2;
				}else{
					b = p.y2-k*p.x2;
				}
				break;
			case 1 :
				k = 1/p.k;
				if(k==Infinity || k==-Infinity){
					b = p.y2;
				}else{
					b = p.y2-k*p.x2;
				}
				break;
			}
		}
		//-------------build funcation
		var rf:Function = function (x, y) {
			var kk:Number = k;
			var bb:Number = b;
			//trace("k="+k+",b="+b)
			if (typeof (x) == "number" && typeof (y) == "string") {
				trace("直线方程:参数类型不正确.");
			}
			if (typeof (x) == "string") {
				if (x == "k") {
					return kk;
				}
				if (x == "b") {
					return bb;
				}
				trace("直线方程:参数不正确");
				return;
			}
			if ((x == undefined || x == null) && (y != undefined && y != null)) {
				return ((y-bb)/kk);
			}
			if ((y == undefined || y == null) && (x != undefined && x != null)) {
				return (kk*x+b);
			}
			if (x != undefined && y != undefined) {
				return (y == (kk*x+b));
			}
		};
		return rf;
	}
	//------------- X 进制转换 N-数,jz,进制
	public static function toX(N:Number, jz:Number, st):String {
		if (st == undefined) {
			st = "";
		}
		if (N<jz) {
			return (_getX(N)+st);
		} else {
			var s0 = Math.floor(N/jz);
			var s1 = _getX((N%jz));
			var s2 = s1+st;
			var s3 = toX(s0, jz, s2);
			return s3;
		}
	}
	public static function _getX(n:Number):String {
		switch (n) {
		case 10 :
			return "A";
			break;
		case 11 :
			return "B";
			break;
		case 12 :
			return "C";
			break;
		case 13 :
			return "D";
			break;
		case 14 :
			return "E";
			break;
		case 15 :
			return "F";
			break;
		default :
			return n.toString();
			break;
		}
	}
	public static function compressBitmapDataToString(rate:Number,bd:BitmapData,keyString:String,mc:MovieClip,onComplitFun:Function,onProcess:Function) {
		if (keyString == undefined) {
			keyString = "0123456789ABCDEF";
		}
		if (rate == undefined) {
			rate = 30;
		}
		var pixs:Array = [];
		
		
		var bdw:Number = bd.width;
		var bdh:Number = bd.height;
		
		var F:Function = X2T(keyString);
		var lastColor:String = "";
		var lastCount:Number = 1;
	
		var color:Number = 0;
		
		mc.keyString = keyString;
		mc.pixs = [];
		mc.bdw = bd.width;
		mc.bdh = bd.height;
		mc.bd = bd;
		mc.lastColor = "";
		mc.lastCount = 1;
		mc.color = 0;
		mc.F = X2T(keyString);
		mc.onComlitFun = onComplitFun;
		mc.onProcess = onProcess;
		mc.rate = rate;
		mc.x = 0;
		mc.y = 0;
		mc.jsq = 0;
		mc.onEnterFrame = function() {
			
			var t = getTimer();
			for (; this.y < this.bdh; this.y++) {
				if (this.x >= this.bdw) {
					this.x = 0;
				}
				for (; this.x < this.bdw; this.x++) {
					this.color = this.bd.getPixel(this.x, this.y);
					
					if (this.lastColor == this.color.toString()) {
						this.lastCount++;
					}else {
						
						if (this.lastColor != "") {
							if (this.lastCount > 1) {
								this.pixs.push(this.F(Number(this.lastColor), false) + "(" + this.lastCount + ")");
							}else {
								this.pixs.push(this.F(Number(this.lastColor), false));
							}
						}
						this.lastCount = 1;
						this.lastColor = this.color.toString();
					}
					//----------------
					if (mc.jsq++ % 5 == 0) {
						//trace(this.x + "|" + this.y);
						this.onProcess(this.y * this.bdw + this.x, this.bdw * this.bdh);
						if (getTimer() - t > (800 / this.rate)) {
							this.x++;
							return;
						}
					}
					//----------------
				}
				
			}
			if (this.lastColor != "") {
				if (this.lastCount > 1) {
					this.pixs.push(this.F(Number(this.lastColor), false) + "(" + this.lastCount + ")");
				}else {
					this.pixs.push(this.F(Number(this.lastColor), false));
				}
			}
			this.onProcess((this.y-1) * this.bdw + this.x, this.bdw * this.bdh);
			this.onComlitFun(this.pixs);
			delete this.onEnterFrame;
		}
		/*
		for (var y:Number = 0; y < bdh; y++) {
			for (var x:Number = 0; x < bdw; x++) {
				color = bd.getPixel(x, y);
				
				if (lastColor == color.toString()) {
					lastCount++;
				}else {
					if (lastColor != "") {
						if (lastCount > 1) {
							pixs.push(F(Number(lastColor), false) + "(" + lastCount + ")");
						}else {
							pixs.push(F(Number(lastColor), false));
						}
					}
					lastCount = 1;
					lastColor = color.toString();
				}
				
			}
		}
		if (lastColor != "") {
			if (lastCount > 1) {
				pixs.push(F(Number(lastColor), false) + "(" + lastCount + ")");
			}else {
				pixs.push(F(Number(lastColor), false));
			}
		}
		
		return pixs;
		*/
	}
	public static function X2T(N:String):Function{
		var f:Function=function(x:String,fx:Boolean){
			var jzArray:String=N;
			var jzl:Number=N.length;
			var f2:Function=function(n:Number,str:String):String{
				var jzArray2:String=N;
				var jzl2:Number=N.length;
				if(n.toString().length<2){
					str=jzArray2.charAt(n)+str;
					return str;
				}else{
					var shang:Number=Math.floor(n/jzl2);
					var yu:Number=int(n%jzl2);
					//trace(jzl2+"--- "+shang+":"+yu);
					str=jzArray2.charAt(yu)+str;
					if(shang==0) return str;
					str=this.call(this,shang,str);
					//Debug.traceAllObj(this);
					return str;
				}
			}
			if(fx){
				var n:Number=0;
				var l:Number=x.length;
				for(var i=0;i<x.length;i++){
					n+=(jzArray.indexOf(x.charAt(i))*Math.pow(jzl,(l-i-1)));
				}
				return n;
			}else{
				return f2.call(f2,Number(x),"");
			}
		}
		return f;
	}
	
function ToTen(rj,jz:Number):Number{
	var c:String=rj.toString();
	var cnexts:String=c.substring(0,c.length-1);
	var cnowAdd:String=c.substring(c.length-1,c.length);
	var nowAdd:Number=getNum(cnowAdd,jz);
	if(rj.length==1) return getNum(cnowAdd,jz);
	return (Number(ToTen(cnexts,jz))*Number(jz)+nowAdd);
}
function getNum(c:String,jz:Number){

	var rt:String=c;
	var st="abcdefghijklmnopqrstuvwxyz";
	var n=st.indexOf(rt.charAt(0));
	if(n!=-1)
	{
		if(n>=(jz-10))
		{
			trace("warning:输入字符["+c+"]超过进制["+jz.toString()+"]允许范围[a～"+st.charAt(jz-11)+"]");
			return NaN;
		}else{
			return (10+n);
		}
	}
	return Number(rt);
}


	//----------------------------------- help
	public static function HELP() {
		var h:String = new String();
		h += "-------------  HELP  --------------\r";
		h += "lineEquation(p:Object, f:Boolean):Function\r";
		h += "建立直线方程 p-参数包含：x0,y0,x1,y1[,x2,y2][,k] f-是否构建与之垂直的方程函数，如果f为true则必须输入x2,y2值(不输入默认为0)\r";
		h += "返回函数(x,y):Object\r";
		h += "x,y输入其中一个值，计算另一个。如果两个都输入，判断该点是否在直线上。如果输入“k”则返回k值，输入“b”则返回b值\r";
		h += "\r";
		h += "toX(N:Number, jz:Number):String\r";
		h += "X 进制转换 N-10进制数值,jz-进制，返回X进制字串\r";
		h += "\r";
		h += "Xpoint(p:Object):Object\r";
		h += "求两直线交点函数 p-参数：[x0,y0,x1,y1,x2,y2,x3,y3][,fun1,fun2][,k1,b1,k2,b2] 三种方式x、y为已知两点,fun为已知两直线方程，k、b为已知两方程的k、b参数返回point类型(.x .y)交点\r";
		h += "\r";
		h += "ToTen(rj,jz:Number):Number\r";
		h += "任何进制（2-26）转10进制\r";
		//h+="\r";
		//h+="\r";
		h += "-------------  HELP  --------------\r";
		trace(h);
	}
}
